//
//  ODBWebViewContainer.swift
//  OBD
//
//  Created by sqkj on 2021/9/14.
//

import UIKit
import WebKit

typealias webViewTitleChangeBlock = (_ title:String) -> ()
typealias webViewLoadProgressBlock = (_ newValue:Float) -> ()
typealias webViewIsLoadingBlock = () -> ()
typealias webViewLoadingShowBlock = (_ show:Bool) -> ()

typealias startLoadBlock = (_ webView:WKWebView) -> ()
typealias webViewStartLoadBlock = (_ webView:WKWebView) -> ()
typealias webViewFinishLoadBlock = (_ webView:WKWebView) -> ()
typealias webViewLoadErrorBlock = (_ webView:WKWebView,_ error:NSError) -> ()

let TITLE_KEYPATH = "title"
let PROGR_KEYPATH = "estimatedProgress"
let LOADING_KEYPATH = "loading"

class ODBWebViewContainer: UIView,WKUIDelegate,WKNavigationDelegate{
    
    var titleDidChangeBlock:webViewTitleChangeBlock?
    var progressChangeBlock:webViewLoadProgressBlock?
    var loadingShowBlock:webViewLoadingShowBlock?
    var webViewTitleChangeBlock:webViewTitleChangeBlock?
    var webViewIsLoadingBlock:webViewIsLoadingBlock?
    var webViewStartLoadBlock:webViewStartLoadBlock?
    var webViewFinishLoadBlock:webViewFinishLoadBlock?
    var webViewLoadErrorBlock:webViewLoadErrorBlock?
    
    lazy var progressView:UIProgressView = {
       let progress = UIProgressView.init()
        progress.trackTintColor = UIColor.white
        progress.progressTintColor = UIColor.blue
        return progress
    }()
    
    
    lazy var webView:WKWebView = {
        let webView = WKWebView.init(frame: CGRect.zero, configuration: ODBWebViewConfiguration())
        webView.uiDelegate = self
        webView.navigationDelegate = self
        webView.allowsBackForwardNavigationGestures = true
        webView.backgroundColor = UIColor.white
        webView.scrollView.bounces = false
        return webView
    }()
    
    init(){
      super.init(frame:CGRect.zero)
      self.makeInit()
    }
    
    override func awakeFromNib() {
        super.awakeFromNib()
        self.makeInit()
    }
    
    override init(frame:CGRect){
        super.init(frame: frame)
        self.makeInit()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        webView.removeObserver(self, forKeyPath: TITLE_KEYPATH, context: nil)
        webView.removeObserver(self, forKeyPath: PROGR_KEYPATH, context: nil)
        webView.removeObserver(self, forKeyPath: LOADING_KEYPATH, context: nil)
    }

    
    // 初始化
    func makeInit(){
        self.bindViewModel()
        self.setupViews()
        self.updateLayoutConstraints()
    }
    
    func bindViewModel (){
        self.registerJsHandler()
        self.addKVO()
    }
    
    func updateLayoutConstraints(){
        self.progressView.snp.makeConstraints { (make) in
            make.top.leading.trailing.equalTo(0)
            make.height.equalTo(2);
        }
        self.webView.snp.makeConstraints { (make) in
            make.edges.equalTo(self)
        }
    }
    
    func setupViews(){
        self.addSubview(self.webView)
        self.addSubview(self.progressView)
    }
    
    // 加载网页字符串地址
    func loadURLstr(url:String){
        let Url = URL.init(string: url)
        self.loadURL(url: Url!)
    }
    
    // 加载网页网址
    func loadURL(url:URL){
       let request = URLRequest.init(url: url)
       self.webView.load(request)
    }
    
    // 加载本地网页
    func loadLocalHtmlFile(name:String){
        let html_URL = Bundle.main.url(forResource: name, withExtension: "html")
        let contentString = try!String(contentsOf: html_URL!, encoding: String.Encoding.utf8)
        self.webView.loadHTMLString(contentString, baseURL: Bundle.main.bundleURL)
    }
    
    // jsbrige
    func registerJsHandler() {
        ///TODO
    }
    
    //MARK:- KVO
    func addKVO(){
        self.webView.addObserver(self, forKeyPath: TITLE_KEYPATH, options: NSKeyValueObservingOptions.new, context: nil)
        self.webView.addObserver(self, forKeyPath: PROGR_KEYPATH, options: NSKeyValueObservingOptions.new, context: nil)
        self.webView.addObserver(self, forKeyPath: LOADING_KEYPATH, options: NSKeyValueObservingOptions.new, context: nil)
    }
    
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        if keyPath == TITLE_KEYPATH{
            let changeValue = change![NSKeyValueChangeKey.newKey] as! String
            if (self.titleDidChangeBlock != nil) {
                self.titleDidChangeBlock!(changeValue)
            }
        }

        if keyPath == PROGR_KEYPATH{
            let changeValue = change![NSKeyValueChangeKey.newKey] as? NSNumber
            self.progressView.progress = changeValue!.floatValue
            self.progressView.isHidden = !(self.progressView.progress<1)
            if (self.progressChangeBlock != nil) {
                self.progressChangeBlock!(self.progressView.progress)
            }
        }
        
        if keyPath == LOADING_KEYPATH{
            let show = change![NSKeyValueChangeKey.newKey] as! Bool
            if (self.loadingShowBlock != nil) {
                self.loadingShowBlock!(show)
            }
        }
    }
    
    //MARK:- WKNavigationDelegate
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        if (self.webViewStartLoadBlock != nil) {
            self.webViewStartLoadBlock!(webView);
        }
    }
    
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        decisionHandler(.allow)
    }
    
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        if (self.webViewLoadErrorBlock != nil) {
            self.webViewLoadErrorBlock!(webView, error as! NSError);
        }
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        if (self.webViewFinishLoadBlock != nil) {
            self.webViewFinishLoadBlock!(webView);
        }
    }
    
    func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
        if !(navigationAction.targetFrame?.isMainFrame)!{
            webView.load(navigationAction.request)
        }
        return WKWebView();
    }
    
    
    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "确定", style: .default, handler: { (_) in
            completionHandler()
        }))
    }
    
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        let alert = UIAlertController(title: nil, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { (_) in
            completionHandler(false)
        }))
        alert.addAction(UIAlertAction(title: "确定", style: .default, handler: { (_) in
            completionHandler(true)
        }))
    }
    
    func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        let alert = UIAlertController(title: nil, message: prompt, preferredStyle: .alert)
        alert.addTextField { (textField) in
            textField.placeholder = defaultText
        }
        alert.addAction(UIAlertAction(title: "确定", style: .default, handler: { (_) in
            completionHandler(alert.textFields?.last?.text)
        }))
    }
}
